package pers.crayon.baseprogram.util;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.Map;

/**
 * HttpUtil
 *
 * @author wangzg13
 * @since 2022/9/22
 */
@Slf4j
public class HttpUtil {

    private static final String CHROME_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36";
    private static final String NORMAL_USER_AGENT = "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)";


    public static String executePost(String url, JSONObject json, String encoding, Header[] headers) throws ParseException, IOException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        String responseBody = "";
        //创建httpclient对象
        CloseableHttpClient client = getCloseableHttpClient();
        //创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);
        //装填参数
        log.debug("request params:{}", json.toString());
        StringEntity requestEntity = new StringEntity(json.toString(), "utf-8");
        requestEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
        //设置参数到请求对象中
        httpPost.setEntity(requestEntity);
        log.debug("request path:{}", url);
        //设置header信息 headers可以传入并遍历map添加
        //指定报文头【Content-type】、【User-Agent】
        //Content-type", "application/x-www-form-urlencoded"
        httpPost.setHeader("Content-type", "application/json");
        httpPost.setHeader("User-Agent", CHROME_USER_AGENT);
        httpPost.setHeaders(headers);
        //执行请求操作，并拿到结果（同步阻塞）
        CloseableHttpResponse response = client.execute(httpPost);
        //获取结果实体
        HttpEntity responseEntity = response.getEntity();
        if (responseEntity != null && response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
            //按指定编码转换结果实体为String类型
            responseBody = EntityUtils.toString(responseEntity, encoding);
        }
        EntityUtils.consume(responseEntity);
        //释放链接
        response.close();
        httpPost.releaseConnection();
        return responseBody;
    }


    /**
     * 链接GET请求
     *
     * @param url
     * @return
     * @throws KeyManagementException
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws ClientProtocolException
     * @throws IOException
     */
    public static String connectGetUrl(String url, Map<String, Object> headers) throws KeyManagementException,
            NoSuchAlgorithmException, KeyStoreException, ClientProtocolException, IOException {
        // 创建httpClient连接对象
        CloseableHttpClient client = getCloseableHttpClient();
        // 创建get请求
        HttpGet httpGet = null;
        CloseableHttpResponse resp = null;
        String jsonString = "";
        try {
            httpGet = new HttpGet(url);
            httpGet.setConfig(getHttpConfig());
            if (headers != null) {
                for (String key : headers.keySet()) {
                    httpGet.addHeader(key, headers.get(key).toString());
                }
            }
            resp = client.execute(httpGet);
            HttpEntity respEntity = resp.getEntity();
            jsonString = EntityUtils.toString(respEntity, "UTF-8");
        } finally {
            //HttpLogPool.pushResp(status, jsonString); 别人的一个终止及时方法
            if (resp != null) {
                try {
                    resp.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (httpGet != null) {
                httpGet.releaseConnection();
            }
        }
        return jsonString;
    }


    /**
     * 配置的接口参数
     *
     * @return
     */
    private static RequestConfig getHttpConfig() {
        return RequestConfig.custom().setSocketTimeout(40000).setConnectTimeout(10000).build();
    }

    /**
     * 获取客户端(httpclient对象)
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws KeyManagementException
     */
    private static CloseableHttpClient getCloseableHttpClient() throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
        /*
         * 默认获取方式为
         * HttpClients.createDefault();
         */
        SSLConnectionSocketFactory sslsf = getSSLConnectionSocketFactory();// TSL/SSL证书配置
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }

    /**
     * 创建没有证书的SSL链接工厂类
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws KeyStoreException
     * @throws KeyManagementException
     */
    private static SSLConnectionSocketFactory getSSLConnectionSocketFactory() throws NoSuchAlgorithmException,
            KeyStoreException, KeyManagementException {
        return new SSLConnectionSocketFactory(
                SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(),
                NoopHostnameVerifier.INSTANCE);
    }
}
